package com.haoshuang.zhouzhoubang.utils

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Log
import com.haoshuang.zhouzhoubang.config.Config
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX
import com.tencent.mm.opensdk.modelmsg.WXImageObject
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage.IMediaObject
import com.tencent.mm.opensdk.modelmsg.WXMiniProgramObject
import com.tencent.mm.opensdk.modelmsg.WXTextObject
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject
import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import java.io.*
import java.net.HttpURLConnection
import java.net.MalformedURLException
import java.net.URL


/** 微信分享工具类  */
class WeChatShareUtil {
    //IWXAPI是第三方app和微信通信的openapi接口
    var api: IWXAPI? = null
    private var context: Context? = null
    var bitmap: Bitmap? = null

    //注册应用id到微信
    private fun regToWx() {
        //通过WXAPIFactory工厂，获取IWXAPI的实例
        api = WXAPIFactory.createWXAPI(context, APP_ID, true)
        //将应用的appId注册到微信
        api?.registerApp(APP_ID)
    }

    /**
     * 分享文字到朋友圈或者好友
     *
     * @param text  文本内容
     * @param scene 分享方式：好友还是朋友圈
     */
    fun shareText(text: String, scene: Int): Boolean {
        //初始化一个WXTextObject对象，填写分享的文本对象
        val textObj = WXTextObject()
        textObj.text = text
        return share(textObj, text, scene)
    }

    /**
     * 分享图片到朋友圈或者好友
     *
     * @param bmp   图片的Bitmap对象
     * @param scene 分享方式：好友还是朋友圈
     */
    fun sharePic(bmp: Bitmap, scene: Int): Boolean {
        val srcBitmap = bmp

        //初始化一个WXImageObject对象
        val imageObj = WXImageObject(srcBitmap)
        //设置缩略图
        val thumb = Bitmap.createScaledBitmap(srcBitmap, 60, 60, true)
//        srcBitmap.recycle()
        return share(imageObj, thumb, scene)
    }

    /**
     * 分享网页到朋友圈或者好友，视频和音乐的分享和网页大同小异，只是创建的对象不同。
     * 详情参考官方文档：
     * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317340&token=&lang=zh_CN
     *
     * @param url         网页的url
     * @param title       显示分享网页的标题
     * @param description 对网页的描述
     * @param scene       分享方式：好友还是朋友圈
     */
    fun shareUrl(
        url: String?,
        title: String?,
        thumb: Bitmap,
        description: String?,
        scene: Int
    ): Boolean {

        //下载网络图片到本地，并转成Bitmap图片(用于分享）
//        String imgUrl = thumbUrll;

//        getNetOrBitmap(imgUrl); //下载图片

        //初试化一个WXWebpageObject对象，填写url
        val webPage = WXWebpageObject()
        webPage.webpageUrl = url
        Log.e("+++++", "shareUrl: $thumb")
        return share(webPage, title, thumb, description, scene)
    }

    /**
     * 分享到小程序
     */
    fun shareMiniProgram(
        title: String,
        srcBitmap: Bitmap,
        description: String,
        path: String,
    ): Boolean {
        val miniProgramObj = WXMiniProgramObject()
        miniProgramObj.webpageUrl = "https://zhouzhoujiafu.com"; // 兼容低版本的网页链接
        miniProgramObj.miniprogramType =
            WXMiniProgramObject.MINIPTOGRAM_TYPE_RELEASE // 正式版:0，测试版:1，体验版:2
        miniProgramObj.userName = "gh_43f9e310a78c"     // 小程序原始id
        miniProgramObj.path = path            //小程序页面路径；对于小游戏，可以只传入 query 部分，来实现传参效果，如：传入 "?foo=bar"
        val thumb = Bitmap.createScaledBitmap(srcBitmap, 250, 200, true)
        return share(miniProgramObj, title, thumb, description, SendMessageToWX.Req.WXSceneSession)
    }

    private fun share(mediaObject: IMediaObject, thumb: Bitmap, scene: Int): Boolean {
        return share(mediaObject, null, thumb, null, scene)
    }

    private fun share(mediaObject: IMediaObject, description: String, scene: Int): Boolean {
        return share(mediaObject, null, null, description, scene)
    }

    private fun share(
        mediaObject: IMediaObject,
        title: String?,
        thumb: Bitmap?,
        description: String?,
        scene: Int
    ): Boolean {
        //初始化一个WXMediaMessage对象，填写标题、描述
        val msg = WXMediaMessage(mediaObject)
        if (title != null) {
            msg.title = title
        }
        if (description != null) {
            msg.description = description
        }
        if (thumb != null) {
            msg.thumbData = bmpToByteArray(thumb, true)
        }
        //构造一个Req
        val req = SendMessageToWX.Req()
        req.transaction = System.currentTimeMillis().toString()
        req.message = msg
        req.scene = scene
        return api!!.sendReq(req)
    }

    //判断是否支持转发到朋友圈
    //微信4.2以上支持，如果需要检查微信版本支持API的情况， 可调用IWXAPI的getWXAppSupportAPI方法,0x21020001及以上支持发送朋友圈
    val isSupportWX: Boolean
        get() {
            val wxSdkVersion = api!!.wxAppSupportAPI
            return wxSdkVersion >= TIMELINE_SUPPORTED_VERSION
        }

    private fun bmpToByteArray(bmp: Bitmap, needRecycle: Boolean): ByteArray {
        val output = ByteArrayOutputStream()
        bmp.compress(Bitmap.CompressFormat.PNG, 100, output)
        if (needRecycle) {
            bmp.recycle()
        }
        val result = output.toByteArray()
        try {
            output.close()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return result
    }

    /**
     * todo 将网络资源图片转换为Bitmap
     * @param imgUrl 网络资源图片路径
     * @return Bitmap
     * 该方法调用时要放在子线程中
     */
    fun netToLoacalBitmap(imgUrl: String?): Bitmap? {
        var bitmap: Bitmap? = null
        var `in`: InputStream? = null
        var out: BufferedOutputStream? = null
        return try {
            `in` = BufferedInputStream(URL(imgUrl).openStream(), 1024)
            val dataStream = ByteArrayOutputStream()
            out = BufferedOutputStream(dataStream, 1024)
            copy(`in`, out)
            out.flush()
            var data = dataStream.toByteArray()
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
            data = null
            bitmap
        } catch (e: IOException) {
            e.printStackTrace()
            null
        }
    }

    @Throws(IOException::class)
    private fun copy(`in`: InputStream, out: OutputStream) {
        val b = ByteArray(1024)
        var read: Int
        while (`in`.read(b).also { read = it } != -1) {
            out.write(b, 0, read)
        }
    }

    /**
     * todo 把网络图片下载到本地保存成Bitmap图片
     * @param imgUrl 网络图片
     */
    private fun getNetOrBitmap(imgUrl: String) {
        try {
            object : Thread() {
                override fun run() {
                    super.run()
                    // 涉及到下载图片，调用netToLoacalBitmap时要放在子线程中
                    bitmap = netToLoacalBitmap(imgUrl)
                }
            }.start()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun returnBitMap(url: String?): Bitmap? {
        Thread {
            var imageurl: URL? = null
            try {
                imageurl = URL(url)
            } catch (e: MalformedURLException) {
                e.printStackTrace()
            }
            try {
                val conn = imageurl!!.openConnection() as HttpURLConnection
                conn.doInput = true
                conn.connect()
                val `is` = conn.inputStream
                bitmap = BitmapFactory.decodeStream(`is`)
                `is`.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }.start()
        return bitmap
    }


    companion object {
        //从官网申请的合法appId
        const val APP_ID = Config.WX_ID
        private const val TIMELINE_SUPPORTED_VERSION = 0x21020001
        var weChatShareUtil: WeChatShareUtil? = null
        fun getInstance(context: Context?): WeChatShareUtil? {
            if (weChatShareUtil == null) {
                weChatShareUtil = WeChatShareUtil()
            }
            if (weChatShareUtil!!.api != null) {
                weChatShareUtil!!.api!!.unregisterApp()
            }
            weChatShareUtil!!.context = context
            weChatShareUtil!!.regToWx()
            return weChatShareUtil
        }
    }
}